/**
 * 对象进入老年代的场景体验一下
 * -XX:NewSize=10485760 -XX:MaxNewSize=10485760 -XX:InitialHeapSize=20971520 -XX:MaxHeapSize=20971520
 * -XX:SurvivorRatio=8  -XX:MaxTenuringThreshold=15 -XX:PretenureSizeThreshold=10485760 -XX:+UseParNewGC
 * -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
 * 运行日志在根目录gc.log，看不懂就画图。
 */
public class ToOldSpace2 {

    public static void main(String[] args) {
        byte[] array1 = new byte[2 * 1024 * 1024];
        array1 = new byte[2 * 1024 * 1024];
        array1 = new byte[2 * 1024 * 1024];

        byte[] array2 = new byte[128 * 1024];
        array2 = null;

        byte[] array3 = new byte[2 * 1024 * 1024];
    }

    /**
     * 首先分配了3个2MB的数组，然后最后让array1变量指向了第三个2MB数组
     *
     * 接着创建了一个128K的数组，但是确让array2指向了null，同时我们一直都知道，Eden区里会有500KB左右的未知对象
     *
     * byte[] array3 = new byte[2 * 1024 * 1024];。此时想要在Eden区里再创建一个2MB的数组，肯定是不行的，所以此时必然触发一次Young GC。
     *
     * 先看如下日志：ParNew: 7260K->573K(9216K), 0.0024098 secs。
     *
     * 这里清晰说明了，本次GC过后，年轻代里就剩下了500多KB的对象
     *
     * 这是为什么呢？此时明明array1变量是引用了一个2MB的数组的啊！
     *
     * 其实道理很简单，大家可以想一下，这次GC的时候，会回收掉上图中的2个2MB的数组和1个128KB的数组，然后留下一个2MB的数组和1个未知的500KB的对象
     *
     * 那么此时剩下来的2MB的数组和500KB的未知对象能放入From Survivor区吗？
     *
     * 答案是：不能
     *
     * 因为Survivor区仅仅只有1MB。根据我们之前说过的规则，此时是不是要把这些存活对象全部放入老年代？
     *
     * 答案：也不是
     *
     * 所以在这里并不是让2MB的数组和500KB的未知对象都进入老年代，而是把500KB的未知对象放入From Survivor区中！
     *
     * 此时老年代里确有2MB的数组，因此可以认为，Young GC过后，发现存活下来的对象有2MB的数组和500KB的未知对象。
     *
     */


}
